package com.ytktt.study.week1.task2;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

/**
 * Xlass文件的类加载器(xlass -> 每个字节都由255-当前字节值)
 *
 * @author ytk
 */
public class XlassClassLoader extends ClassLoader {

    private static final String PREFIX_PATH = "/xlass/";
    private static final String SUFFIX = ".xlass";
    private static final int BUFFER_SIZE = 4096;

    public static void main(String[] args) throws Exception {
        Class<?> helloClass = new XlassClassLoader().findClass("Hello");
        Method helloMethod = helloClass.getMethod("hello");
        helloMethod.invoke(helloClass.newInstance());
    }

    @Override
    protected Class<?> findClass(String name) {
        if (name == null || "".equals(name)) {
            throw new IllegalArgumentException("name is invalid");
        }
        InputStream is = this.getClass().getResourceAsStream(PREFIX_PATH + name + SUFFIX);
        if (is == null) {
            throw new IllegalArgumentException("can't find " + PREFIX_PATH + name + SUFFIX);
        }
        byte[] bytes = toByteArray(is);
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (255 - bytes[i]);
        }
        return defineClass(name, bytes, 0, bytes.length);
    }

    private static byte[] toByteArray(InputStream is) {
        try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[BUFFER_SIZE];
            int n;
            while (-1 != (n = is.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("err: load xlass fail");
        }
        return null;
    }
}
